package com.keray.web.push.store.impl;

import com.alibaba.fastjson.JSON;
import com.keray.web.push.ClientMessageData;
import com.keray.web.push.MessageType;
import com.keray.web.push.store.MessageDataStore;
import org.bson.types.ObjectId;
import org.springframework.context.annotation.Primary;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.List;
import java.util.stream.Collectors;

import static org.springframework.data.mongodb.core.query.Criteria.where;
import static org.springframework.data.mongodb.core.query.Query.query;
import static org.springframework.data.mongodb.core.query.Update.update;

/**
 * @author by keray
 * date:2021/7/26 2:00 下午
 */
@Component
@Primary
public class MongoMessageStore implements MessageDataStore {

    @Resource
    private MongoTemplate template;

    @Override
    public String insertMessage(ClientMessageData data) {
        return template.insert(MongoMessageModel.builder()
                .message(data.getVersion() == 1 ? JSON.parse(data.getMessage()) : data.getMessage())
                .channel(data.getChannel())
                .retry(data.getRetry())
                .type(data.getType())
                .service(data.getService())
                .targetId(data.getTargetId())
                .flag(false)
                .createdTime(LocalDateTime.now())
                .version(data.getVersion())
                .build()).getId();
    }

    @Override
    public void sendOk(String messageId) {
        template.upsert(query(where("_id").is(new ObjectId(messageId))),
                update("flag", true).set("sendTime", LocalDateTime.now()),
                MongoMessageModel.class);
    }

    @Override
    public List<ClientMessageData> uidAll(MessageType type, String service, String uid) {
        return template.query(MongoMessageModel.class).matching(
                        query(where("type").is(type).and("channel").is(0).and("service").is(service).and("targetId").is(uid))
                ).all().stream()
                .map(data -> ClientMessageData.builder()
                        .message(data.getVersion() == 1 ? JSON.toJSONString(data.getMessage()) : data.getMessage().toString())
                        .channel(data.getChannel())
                        .retry(data.getRetry())
                        .type(data.getType())
                        .service(data.getService())
                        .targetId(data.getTargetId())
                        .messageId(data.getId())
                        .build())
                .collect(Collectors.toList());
    }

    @Override
    public List<ClientMessageData> uidAllNotSend(MessageType type, String service, String uid) {
        return template.query(MongoMessageModel.class).matching(
                        query(where("type").is(type).and("channel").is(0).and("service").is(service).and("targetId").is(uid).and("flag").is(false))
                ).all().stream()
                .map(data -> ClientMessageData.builder()
                        .messageId(data.getId())
                        .message(data.getVersion() == 1 ? JSON.toJSONString(data.getMessage()) : data.getMessage().toString())
                        .channel(data.getChannel())
                        .retry(data.getRetry())
                        .type(data.getType())
                        .service(data.getService())
                        .targetId(data.getTargetId())
                        .version(data.getVersion())
                        .save(true)
                        .build())
                .collect(Collectors.toList());
    }

    @Override
    public List<ClientMessageData> groupAll(MessageType type, String service, String group) {
        return null;
    }

    @Override
    public List<ClientMessageData> groupNotSendAllByUid(MessageType type, String service, String group, String uid) {
        return null;
    }
}
